import java.util.Vector;
import javax.swing.JTable;

/**
 * GraphADT is a generic interface for representing both directed
 * and undirected graphs.
 * @param VA Type representing vertices.
 * @param EA Type representing edges.
 *
 * @version 1.0
 * @author K.Vamsi Krishna
 */
interface GraphADT <VA,EA>
{
	/**
	 * Used to indicate that the graph is directed.
	 */
	public static final boolean DIRECTED = true;
	/**
	 * Used to indicate that the graph is undirected.
	 */
	public static final boolean UNDIRECTED = false;

	/**
	 * Returns the number of vertices in the graph.
	 */	
	public int numVertices();
	/**
	 * Returns the number of edges in the graph.
	 */
	public int numEdges();
	/**
	 * Returns the type of the graph.
	 * @return True if the graph is directed, false if undirected.
	 */	
	public boolean isDirected();
	/**
	 * Adds an edge between vertex "from" and vertex "to" only when there is
	 * no existing edge between them. Self loops cannot be added. It makes a copy
	 * of ea and doesnot refer to it later.
	 * Raises IllegalVertexException if "from" or "to" denotes an invalid vertex.
	 * @param ea Refers to the EA object to be attached with the new edge
	 */
	public void addEdge(int from, int to,EA  ea) throws IllegalVertexException;
	/**
	 * Removes an edge between vertex "from" and vertex "to" if there exists
	 * an edge between them.
	 * Raises IllegalVertexException if "from" or "to" denotes an invalid vertex.
	 * @return EA object corresponding to the deleted edge or null when there was no edge
	 */
	public EA removeEdge(int from, int to) throws IllegalVertexException;
	/**
	 * Returns an edge between vertex "from" and vertex "to" if there exists
	 * an edge between them. The object returned is only a copy of the actual edge,
	 * so the changes made to it will not effect the actual edge.
	 * Raises IllegalVertexException if "from" or "to" denotes an invalid vertex.
	 * @return EA object corresponding to the edge or null when there is no edge.
	 */
	public EA getEdge(int from, int to) throws IllegalVertexException;
	/**
	 * Sets new EA object for the edge between vertex "from" and vertex "to"
	 * if there exists an edge between them.It makes a copy of ea and doesnot
	 * refer to it later.
	 * Raises IllegalVertexException if "from" or "to" denotes an invalid vertex.
	 * @param ea Refers to the EA object to be attached with the new edge
	 */
	public void setEdge(int from, int to, EA ea) throws IllegalVertexException;
	/**
	 * Returns true if there exists an edge from "from" to "to".
	 * Raises IllegalVertexException if "from" or "to" denotes an invalid vertex.
	 */	
	public boolean edgeExists(int from, int to) throws IllegalVertexException;
	/**
	 * Add an new vertex and attachs "va" with it. It makes a copy of va and
	 * doesnot refer to the passed object later.
	 * @param va Is a VA object to be attached to the new vertex.
	 * @return The vertex number of the newly created vertex.
	 */
	public int addVertex(VA va);
	/**
	 * Removes a vertex and hence all its corresponding edges.
	 * Removing a vertex automatically decrease the vetex number by 1 for all the
	 * vertices that followed the deleted vertex.
	 * Raises IllegalVertexException if v denotes an invalid vertex
	 * @return VA object of the deleted vetex
	 */
	public VA removeVertex(int v) throws IllegalVertexException;
	/**
	 * Returns the VA object corresponding to the specified vertex.
	 * The object returned is only a copy of the actual vertex,
	 * so the changes made to it will not effect the actual vertex.
	 * Raises an IllegalVertexException if v denotes an invalid vertex.
	 */
	public VA getVertex(int v) throws IllegalVertexException;
	/**
	 * Attaches a new VA objects to the specified vertex.  It makes a copy 
	 * of va and doesnot refer to the passed object later.
	 * Raises an IllegalVertexException if v denotes an invalid vertex.
	 */
	public void setVertex(int v, VA va) throws IllegalVertexException;
	/**
	 * Returns the number of edges in to this vertex.
	 * Raises an IllegalVertexException if v denotes an invalid vertex.
	 * For undirected graphs both inDegree() and outDegree() return the
	 * same value denoting the degree of the vertex.
	 */	
	public int inDegree(int v) throws IllegalVertexException;
	/**
	 * Returns the number of edges out of this vertex.
	 * Raises an IllegalVertexException if v denotes an invalid vertex.
	 * For undirected graphs both inDegree() and outDegree() return the
	 * same value denoting the degree of the vertex.
	 */
	public int outDegree(int v) throws IllegalVertexException;
	/**
	 * Give the list of all vertices adjacent to the given vertex.
	 * Raises an IllegalVertexException if v denotes an invalid vertex.
	 * @return Vector with Integer objects as elements.
	 */
	public Vector<Integer> getNeighbours(int v) throws IllegalVertexException;
	/**
	 * Give the list of all vertices for which the given vertex is adjacent.
	 * Raises an IllegalVertexException if v denotes an invalid vertex.
	 * @return Vector with Integer objects as elements.
	 */
	public Vector<Integer> getNeighbourFor(int v) throws IllegalVertexException;
	/**
	 * Removes all edges incident to or from vertex v.
	 * Throws IllegalVertexException if v is an invalid vertex.
	 */
	public void removeAllEdges(int v) throws IllegalVertexException;
	/**
	 * Returns the adjaceny matrix (edge weights). If there is no edge its weight is
	 * loaded with 0. For undirected graphs the matrix is symmetric.
	 * @return A JTable object with rows and columns appropriately loaded.
	 */
	public JTable getAdjMatrix() throws IllegalVertexException;
	/**
	 * Sets new weights for all edges (new edges are created by this function
	 * if the weight becomes non-zero and existing edges are removed if the 
	 * weight becomes zero).
	 * For undirected graphs the matrix passed is expected to be symmetric,
	 * otherwise it may give unexpected results.
	 * @param adjMatrixTable is JTabel object loaded with new weights.
	 */
	public void setAdjMatrix(JTable adjMatrixTable) throws IllegalVertexException;
}
